home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 November
/
Macworld (1999-11).dmg
/
Updaters
/
WhiteCap 3.0.4
/
WhiteCap Source.sit
/
WhiteCap Source
/
Common
/
EgOSUtils.cpp
next >
Wrap
C/C++ Source or Header
|
1999-08-01
|
12KB
|
598 lines
#include "EgOSUtils.h"
#include "CEgFileSpec.h"
#include "CEgErr.h"
#include "UtilStr.h"
#include <stdlib.h>
#include <time.h>
#ifdef EG_MAC
#include <Resources.h>
#include <Sound.h>
#endif
#ifdef EG_WIN
#include <windows.h>
#endif
int EgOSUtils::sXdpi = 72;
int EgOSUtils::sYdpi = 72;
long EgOSUtils::sLastCursor = -1;
long EgOSUtils::sLastCursorChange = -1;
CEgFileSpec EgOSUtils::sAppSpec;
void EgOSUtils::ShowFileErr( const UtilStr* inName, char* inErrMsg, bool wasReading ) {
UtilStr s;
if ( wasReading )
s.Assign( "Error reading : " );
else
s.Assign( "Error writing : " );
s.Append( inErrMsg );
#ifdef EG_MAC
s.Insert( 14, "“”" );
#else
s.Insert( 14, "\"\"" );
#endif
s.Insert( 15, inName );
ShowMsg( s );
}
void EgOSUtils::ShowFileErr( const UtilStr* inName, CEgErr& inErr, bool wasReading ) {
UtilStr msg;
inErr.GetErrStr( msg );
ShowFileErr( inName, msg.getCStr(), wasReading );
}
void EgOSUtils::ShowFileErr( const CEgFileSpec& inFileSpec, CEgErr& inErr, bool wasReading ) {
UtilStr msg, fileName;
inFileSpec.GetFileName( fileName );
inErr.GetErrStr( msg );
ShowFileErr( &fileName, msg.getCStr(), wasReading );
}
void EgOSUtils::Initialize() {
srand( clock() );
#if EG_MAC
OSStatus status;
FCBPBRec fcbPBRec;
Str255 appName;
FSSpec spec;
fcbPBRec.ioCompletion = nil;
fcbPBRec.ioFCBIndx = 0;
fcbPBRec.ioVRefNum = 0;
fcbPBRec.ioRefNum = ::CurResFile();
fcbPBRec.ioNamePtr = appName;
status = ::PBGetFCBInfoSync(&fcbPBRec);
::FSMakeFSSpec(fcbPBRec.ioFCBVRefNum, fcbPBRec.ioFCBParID, appName, &spec );
sAppSpec.Assign( &spec, 0 );
#endif
#ifdef EG_WIN
HDC hDC = ::CreateDC( "DISPLAY", NULL, NULL, NULL );
if ( hDC ) {
sXdpi = ::GetDeviceCaps( hDC, LOGPIXELSX );
sYdpi = ::GetDeviceCaps( hDC, LOGPIXELSY );
::DeleteDC( hDC );
}
char path[ 700 ];
long len = ::GetModuleFileName( NULL, path, 699 );
if ( len ) {
UtilStr fdir( path, len );
fdir.Keep( fdir.FindLastInstanceOf( '\\' ) );
sAppSpec.Assign( fdir.getCStr(), 0 );
}
/*
UtilStr prefPath;
char path[ 500 ];
if ( ::GetCurrentDirectory( 495, path ) ) {
prefPath.Assign( path );
prefPath.Append( '\\' );
sAppSpec.Assign( prefPath.getCStr(), 0 );
}*/
#endif
// For mac, sXspi and sYdpi are already correct by default
}
bool EgOSUtils::AskSaveAs( const char* inPrompt, const char* inDefaultName, CEgFileSpec& outSpec, long inFileType ) {
UtilStr inName( inDefaultName );
return AskSaveAs( inPrompt, inName, outSpec, inFileType );
}
#ifdef EG_ZINC
#include <z_fildlg.hpp>
#endif
bool EgOSUtils::AskSaveAs( const char* inPrompt, const UtilStr& inDefaultName, CEgFileSpec& outSpec, long inFileType ) {
int doSave = false;
UtilStr prompt( inPrompt );
#ifdef EG_MAC
StandardFileReply reply;
//::UDesktop::Deactivate();
::StandardPutFile( prompt.getPasStr(), inDefaultName.getPasStr(), &reply );
//::UDesktop::Activate();
if (reply.sfGood) {
outSpec.Assign( &reply.sfFile, inFileType );
doSave = true;
}
#endif
#if EG_WIN && EG_ZINC
UtilStr defName( inDefaultName );
ZafFileDialog fileDialog( 20, 5, 60, 14 );
if ( inFileType )
CEgFileSpec::TypeToExt( defName, inFileType );
fileDialog.SetFile( defName.getCStr() );
if ( fileDialog.GetFile( ZAF_FILE_DIALOG_SAVEAS ) == S_DLG_OK ) {
doSave = true;
outSpec.Assign( fileDialog.File(), inFileType );
}
/*
unsigned char c;
UtilStr winFilter;
OPENFILENAME paramBlk;
char pathName[ 601 ];
inDefaultName.copyTo( pathName, 600 );
// See page 519 of Vol 5 in Win32 Ref for descrip of the lpstrFilter scheme.
winFilter.Append( "/0*" );
// Append the ext mask...
for ( int d = 0; d <= 24; d += 8 ) { // Go thru each byte in ID num
c = ((inFileType << d) >> 24 );
winFilter.Append( (char) c );
}
winFilter.Append( (char) 0 ); // Windows exptects an extra NUL to end the filter
memset( ¶mBlk, 0, sizeof(OPENFILENAME) );
paramBlk.lStructSize = sizeof(OPENFILENAME);
paramBlk.lpstrFilter = winFilter.getCStr();
paramBlk.lpstrFile = pathName;
paramBlk.nMaxFile = 600;
paramBlk.lpstrTitle = prompt.getCStr();
if ( ::GetSaveFileName( ¶mBlk ) ) {
outSpec.Assign( pathName );
doSave = true;
}*/
#endif
return doSave;
}
bool EgOSUtils::AskOpen( const char* inPrompt, CEgFileSpec& outSpec, long inTypeMask ) {
bool didOpen = false;
UtilStr prompt( inPrompt );
#ifdef EG_MAC
StandardFileReply macFileReply;
SFTypeList typeList;
//UDesktop::Deactivate();
typeList[0] = inTypeMask;
::StandardGetFile( NULL, inTypeMask ? 1 : 0, typeList, &macFileReply );
//UDesktop::Activate();
if ( macFileReply.sfGood ) {
outSpec.Assign( &macFileReply.sfFile );
didOpen = true;
}
#endif
#if EG_WIN && EG_ZINC
ZafFileDialog fileDialog( 5, 5, 60, 14 );
UtilStr str( "*" );
if ( inTypeMask ) {
CEgFileSpec::TypeToExt( str, inTypeMask );
fileDialog.SetFilter( str.getCStr() );
}
if ( fileDialog.GetFile( ZAF_FILE_DIALOG_OPEN ) == S_DLG_OK ) {
char path[ 401 ];
didOpen = true;
fileDialog.FullPath( path, 400 );
outSpec.Assign( path );
}
/*
unsigned char c;
UtilStr winFilter;
OPENFILENAME paramBlk;
char pathName[ 601 ];
// See page 519 of Vol 5 in Win32 Ref for descrip of the lpstrFilter scheme.
winFilter.Append( "/0*" );
// Append the ext mask...
for ( int d = 0; d <= 24; d += 8 ) { // Go thru each byte in ID num
c = ((inTypeMask << d) >> 24 );
winFilter.Append( (char) c );
}
winFilter.Append( (char) 0 ); // Windows exptects an extra NUL to end the filter
memset( ¶mBlk, 0, sizeof(OPENFILENAME) );
paramBlk.lStructSize = sizeof(OPENFILENAME);
paramBlk.lpstrFilter = winFilter.getCStr();
paramBlk.lpstrFile = pathName;
paramBlk.nMaxFile = 600;
paramBlk.lpstrTitle = prompt.getCStr();
if ( ::GetOpenFileName( ¶mBlk ) ) {
outSpec.Assign( pathName );
didOpen = true;
}*/
#endif
return didOpen;
}
bool EgOSUtils::AreYouSure( const UtilStr& inMsg ) {
int ans;
#ifdef EG_MAC
::ParamText( inMsg.getPasStr(), "\p", "\p", "\p");
//UDesktop::Deactivate();
ans = ::CautionAlert( 2000, NULL );
//UDesktop::Activate();
return ans == 1; //answer_Save;
#endif
#ifdef EG_WIN
ans = ::MessageBox( NULL, inMsg.getCStr(), "Examgen Message", MB_ICONEXCLAMATION | MB_YESNO | MB_SETFOREGROUND | MB_TASKMODAL );
return ans == IDYES;
#endif
}
bool EgOSUtils::AreYouSure( const char* inMsg ) {
UtilStr msg( inMsg );
return AreYouSure( msg );
}
int EgOSUtils::AskSaveChanges( const char* inName ) {
UtilStr name( inName );
return AskSaveChanges( name );
}
int EgOSUtils::AskSaveChanges( const UtilStr& inName ) {
int ans;
#ifdef EG_MAC
::ParamText( inName.getPasStr(), "\p", "\p", "\p" );
//UDesktop::Deactivate();
ans = ::CautionAlert( 2001, NULL );
//UDesktop::Activate();
return 2 - ans;
#endif
#ifdef EG_WIN
UtilStr msg( "Save changes to \"" );
msg.Append( inName );
msg.Append( "\" before closing?" );
ans = ::MessageBox( NULL, msg.getCStr(), "Examgen Message", MB_ICONEXCLAMATION | MB_YESNOCANCEL | MB_SETFOREGROUND | MB_TASKMODAL );
if ( ans == IDYES )
return 1;
else if ( ans == IDNO )
return -1;
else
return 0;
#endif
}
void EgOSUtils::SpinCursor() {
long time = clock();
if ( sLastCursorChange == -1 )
sLastCursorChange = time;
else if ( time - CLOCKS_PER_SEC / 3 > sLastCursorChange ) { // Every 1/3 second...
#ifdef EG_MAC
Handle cursHndl;
sLastCursor = ( sLastCursor + 1 ) % 8; // 8 Cursors
cursHndl = ::GetResource( 'CURS', 6500 + sLastCursor ); // 6500 = Base ID
sLastCursorChange = time;
if ( cursHndl )
::SetCursor( (Cursor*) *cursHndl );
#endif
#ifdef EG_WIN
SetCursor( ::LoadCursor( NULL, IDC_WAIT ) );
sLastCursor = 1;
#endif
}
}
void EgOSUtils::ShowCursor() {
#ifdef EG_MAC
::ShowCursor();
::InitCursor();
#endif
#ifdef EG_WIN
::SetCursor( ::LoadCursor( NULL, IDC_ARROW ) );
while ( ::ShowCursor( true ) < 0 ) { }
#endif
sLastCursor = -1;
sLastCursorChange = -1;
}
void EgOSUtils::HideCursor() {
#ifdef EG_MAC
::HideCursor();
#endif
#ifdef EG_WIN
while ( ::ShowCursor( false ) >= 0 ) { }
#endif
sLastCursor = -1;
sLastCursorChange = -1;
}
bool EgOSUtils::GetNextFile( const CEgFileSpec& folderSpec, CEgFileSpec& outSpec, bool inStartOver, bool inFolders ) {
bool ok;
#ifdef EG_MAC
static int sLastIndex;
OSErr err;
HFileInfo pb;
FSSpec spec;
long parID;
Str255 str;
parID = ( (FSSpec*) folderSpec.OSSpec() ) -> parID;
pb.ioVRefNum = ( (FSSpec*) folderSpec.OSSpec() ) -> vRefNum;
pb.ioNamePtr = str;
if ( inStartOver )
pb.ioFDirIndex = 1;
else
pb.ioFDirIndex = sLastIndex;
ok = false;
do {
pb.ioDirID = parID;
err = PBGetCatInfoSync( (CInfoPBRec*) &pb );
if ( err == noErr && ( (pb.ioFlFndrInfo.fdFlags & fInvisible) == 0) /*&& pb.ioFlFndrInfo.fdCreator == cEGCreator*/ ) {
ok = ( (pb.ioFlAttrib & ioDirMask ) == 0 );
if ( inFolders )
ok = ! ok;
if ( ok ) {
if ( inFolders )
pb.ioFlParID = pb.ioDirID;
::FSMakeFSSpec( pb.ioVRefNum, pb.ioFlParID, str, &spec );
outSpec.Assign( &spec, pb.ioFlFndrInfo.fdType );
}
}
pb.ioFDirIndex++;
sLastIndex = pb.ioFDirIndex;
} while ( err == noErr && ! ok );
#endif
#ifdef EG_WIN
WIN32_FIND_DATA fileData;
static HANDLE hSearch;
UtilStr name;
bool isDir, tryAgain;
do {
if ( inStartOver ) {
inStartOver = false;
name.Assign( (char*) folderSpec.OSSpec() );
if ( name.getChar( name.length() ) == '\\' )
name.Trunc( 1 );
ok = SetCurrentDirectory( name.getCStr() );
if ( ok ) {
hSearch = ::FindFirstFile( "*.*", &fileData );
ok = hSearch != INVALID_HANDLE_VALUE;
} }
else
ok = ::FindNextFile( hSearch, &fileData );
if ( ok ) {
name.Assign( fileData.cFileName );
isDir = ::GetFileAttributes( fileData.cFileName ) & FILE_ATTRIBUTE_DIRECTORY;
if ( isDir == inFolders ) {
tryAgain = name.compareTo( "." ) == 0 || name.compareTo( ".." ) == 0;
outSpec.Assign( folderSpec );
if ( isDir )
name.Append( "\\" );
outSpec.Rename( name ); }
else
tryAgain = true;
}
} while ( ok && tryAgain );
#endif
return ok;
}
void EgOSUtils::Beep() {
#ifdef EG_MAC
::SysBeep( 200 );
#endif
#ifdef EG_WIN
MessageBeep(0);
#endif
}
long EgOSUtils::CurTimeMS() {
#if EG_WIN
return ::timeGetTime();
#else
return ::TickCount() * 16;
#endif
}
void EgOSUtils::GetMouse( Point& outPt ) {
#if EG_MAC
::GetMouse( &outPt );
::LocalToGlobal( &outPt );
#endif
#if EG_WIN
POINT p;
::GetCursorPos( &p );
outPt.h = p.x;
outPt.v = p.y;
#endif
}
void EgOSUtils::ShowMsg( const UtilStr& inMsg ) {
#ifdef EG_MAC
//UDesktop::Deactivate();
::ParamText( inMsg.getPasStr(), "\p", "\p", "\p");
::StopAlert( 2002, NULL );
//#pragma rem back in!
//UDesktop::Activate();
#endif
#ifdef WIN32
::MessageBox( NULL, inMsg.getCStr(), "Examgen Message", MB_ICONEXCLAMATION | MB_OK | MB_SETFOREGROUND | MB_APPLMODAL );
//ZafMessageWindow* w = new ZafMessageWindow( "Message", ZAF_EXCLAMATION_ICON, ZAF_DIALOG_OK, ZAF_DIALOG_OK, inMsg.getCStr() );
//zafWindowManager -> Add( w );
//w -> Control();
#endif
}
void EgOSUtils::ShowMsg( const char* inMsg ) {
UtilStr msg( inMsg );
ShowMsg( msg );
}
long EgOSUtils::Rnd( long min, long max ) {
long maxRnd = RAND_MAX;
long retNum = rand() * ( max - min + 1 ) / maxRnd + min;
if ( retNum >= max )
return max;
else
return retNum;
}
unsigned long EgOSUtils::RevBytes( unsigned long inNum ) {
return ( inNum << 24 ) | ( ( inNum & 0xFF00 ) << 8 ) | ( ( inNum & 0xFF0000 ) >> 8 ) | ( inNum >> 24 );
}